import 'terms.dart';

/// 组合判定
String judgeCombineTerms(Board board, ChessStep chessStep,
    {bool isForce = false}) {
  var finalTerms = Terms.none;

  /// 点方 1S8x2S13x2S3
  bool reJudgeDotSquare() {
    List s8List = sCount(board, chessStep, 8, true);
    List s13List = sCount(board, chessStep, 5, false);
    List s3List = sCount(board, chessStep, 4, false);
    if (s8List.length == 1 && s13List.length == 2 && s3List.length == 2) {
      final step8 = s8List.first;
      // 检查y坐标
      final y8 = step8.y;
      bool yCondition = s3List.any((step3) => step3.y == y8) &&
          s13List.any((step13) => step13.y == y8);

      // 检查x坐标
      final x8 = step8.x;
      bool xCondition = s3List.any((step3) => step3.x == x8) &&
          s13List.any((step13) => step13.x == x8);

      if (yCondition && xCondition) {
        return true;
      }
    }
    return false;
  }

  /// 跳方
  bool reJudgeJumpSquare() {
    // printInfo('进入跳方的判定');
    List s8List = sCount(board, chessStep, 8, true);
    List s6List = sCount(board, chessStep, 4, true);
    List s7List = sCount(board, chessStep, 5, true);
    if (s8List.length == 1 && s6List.length == 2 && s7List.length == 2) {
      final step8 = s8List.first;
      // 检查y坐标
      final y8 = step8.y;
      bool yCondition = s6List.any((step6) => step6.y == y8) &&
          s7List.any((step7) => step7.y == y8);

      // 检查x坐标
      final x8 = step8.x;
      bool xCondition = s6List.any((step6) => step6.x == x8) &&
          s7List.any((step7) => step7.x == x8);

      if (yCondition || xCondition) {
        return true;
      }
    }
    return false;
  }

  /// 小伸腿
  bool judgeSmallLedge() {
    List s7List = sCount(board, chessStep, 5, true);
    if (s7List.isEmpty) {
      return false;
    }
    var desc = calculateDirection(chessStep.toGtp());
    ChessStep coordinate7 = s7List.first;
    var desc7 = calculateDirection(coordinate7.toGtp());
    if (isOneLine(desc!) && isTwoLine(desc7!)) {
      return true;
    }
    return false;
  }

  /// 大伸腿
  bool judgeBigLedge() {
    List s10List = sCount(board, chessStep, 10, true);
    if (s10List.isEmpty) {
      return false;
    }
    var desc = calculateDirection(chessStep.toGtp());
    ChessStep coordinate10 = s10List.first;
    var desc10 = calculateDirection(coordinate10.toGtp());
    if (isOneLine(desc!) && isTwoLine(desc10!)) {
      return true;
    }
    return false;
  }

  String forceJudge() {
    var desc = calculateDirection(chessStep.toGtp());
    List s7List = sCount(board, chessStep, 5, true);
    if (s7List.isNotEmpty) {
      ChessStep coordinate7 = s7List.first;
      var terms = judgeSpecialTerms(board, coordinate7);
      var desc7 = calculateDirection(coordinate7.toGtp());
      if (terms.contains(Terms.superOutsideEye.desc) && isStar(desc!) ||
          (judgeSpecialTerms(board, chessStep)
                  .contains(Terms.superOutsideEye.desc) &&
              isStar(desc7!))) {
        return Terms.kEnclosureSmallFlyEnclosure.desc;
      }

      if (terms == Terms.outsideEye.desc &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.smallEye.desc) ||
          (judgeSpecialTerms(board, chessStep)
                  .contains(Terms.outsideEye.desc) &&
              terms.contains(Terms.smallEye.desc))) {
        return Terms.kEnclosureWorryFreeCorner.desc;
      }
    }

    List s6List = sCount(board, chessStep, 4, true);
    if (s6List.isNotEmpty) {
      ChessStep coordinate6 = s6List.first;
      var terms = judgeSpecialTerms(board, coordinate6);
      var desc6 = calculateDirection(coordinate6.toGtp());
      if (terms == Terms.superHighPoint.desc && isStar(desc!) ||
          judgeSpecialTerms(board, chessStep)
                  .contains(Terms.superHighPoint.desc) &&
              isStar(desc6!)) {
        return Terms.kEnclosureDgEnclosure.desc;
      }

      if (terms.contains(Terms.highPoint.desc) &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.starPoint.desc) ||
          (isStar(desc6!) &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.highPoint.desc))) {
        return Terms.kEnclosureSmallJumpEnclosure.desc;
      }

      if (terms.contains(Terms.superHighPoint.desc) &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.smallEye.desc) ||
          (judgeSpecialTerms(board, coordinate6)
                  .contains(Terms.smallEye.desc) &&
              terms.contains(Terms.highPoint.desc))) {
        return Terms.kEnclosureDgEnclosure.desc;
      }
    }

    List s10List = sCount(board, chessStep, 10, true);
    if (s10List.isNotEmpty) {
      ChessStep coordinate10 = s10List.first;
      var terms = judgeSpecialTerms(board, coordinate10);
      if (terms.contains(Terms.superOutsideEye.desc) &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.smallEye.desc) ||
          (judgeSpecialTerms(board, chessStep)
                  .contains(Terms.superOutsideEye.desc) &&
              terms.contains(Terms.smallEye.desc))) {
        return Terms.kEnclosureBigFlyEnclosure.desc;
      }
    }

    List s9List = sCount(board, chessStep, 9, true);
    if (s9List.isNotEmpty) {
      ChessStep coordinate9 = s9List.first;
      var terms = judgeSpecialTerms(board, coordinate9);
      if (terms.contains(Terms.superHighPoint.desc) && isStar(desc!) ||
          (terms.contains(Terms.superHighPoint.desc)) &&
              judgeSpecialTerms(board, chessStep)
                  .contains(Terms.superHighPoint.desc)) {
        return Terms.kEnclosureBigJumpEnclosure.desc;
      }
    }

    List s13List = sCount(board, chessStep, 5, false);
    if (s13List.isNotEmpty) {
      ChessStep coordinate13 = s13List.first;
      var terms = judgeSpecialTerms(board, coordinate13);
      var desc13 = calculateDirection(coordinate13.toGtp());
      if (judgeSpecialTerms(board, chessStep)
              .contains(Terms.superOutsideEye.desc) &&
          isStar(desc13!)) {
        return Terms.cornerApproachSmallFlyApproachMove.desc;
      }

      if (judgeSpecialTerms(board, chessStep).contains(Terms.smallEye.desc) &&
          terms.contains(Terms.outsideEye.desc)) {
        return Terms.cornerApproachSmallEyeEnclosure.desc;
      }

      if (judgeSpecialTerms(board, chessStep).contains(Terms.outsideEye.desc) &&
          terms.contains(Terms.smallEye.desc)) {
        return Terms.cornerApproachSmallFlyEnclosure.desc;
      }
    }

    List<ChessStep> s3List = sCount(board, chessStep, 4, false);
    if (s3List.isNotEmpty) {
      ChessStep coordinate3 = s3List.first;
      var terms = judgeSpecialTerms(board, coordinate3);
      var desc3 = calculateDirection(coordinate3.toGtp());
      if (judgeSpecialTerms(board, chessStep)
              .contains(Terms.superHighPoint.desc) &&
          isStar(desc3!)) {
        return Terms.cornerApproachHighHangStar.desc;
      }

      if (judgeSpecialTerms(board, chessStep).contains(Terms.smallEye.desc) &&
          terms.contains(Terms.highPoint.desc)) {
        return Terms.cornerApproachSmallEyeEnclosure.desc;
      }

      if (judgeSpecialTerms(board, chessStep).contains(Terms.highPoint.desc) &&
          terms.contains(Terms.smallEye.desc)) {
        return Terms.cornerApproachHighHang.desc;
      }
    }

    List s15list = sCount(board, chessStep, 10, false);
    if (s15list.isNotEmpty) {
      ChessStep coordinate15 = s15list.first;
      var terms = judgeSpecialTerms(board, coordinate15);
      if (terms.contains(Terms.smallEye.desc) &&
          judgeSpecialTerms(board, chessStep)
              .contains(Terms.superOutsideEye.desc)) {
        return Terms.cornerApproachBigFlyCornerApproach.desc;
      }
    }

    List<ChessStep> s14List = sCount(board, chessStep, 14, true);
    if (s14List.isNotEmpty) {
      ChessStep coordinate14 = s14List.first;
      var terms = judgeSpecialTerms(board, coordinate14);
      if (terms.contains(Terms.superHighPoint.desc) &&
          judgeSpecialTerms(board, chessStep)
              .contains(Terms.superHighPoint.desc)) {
        return Terms.cornerApproachTwoHighHang.desc;
      }
    }

    // if (finalTerms.desc.contains(Terms.block.desc)) {
    //   if (judgeInvasion(board, chessStep)) {
    //     finalTerms = Terms.invasion;
    //   }
    // }
    // printInfo('强判定：${finalTerms.desc}');
    return finalTerms.desc;
  }

  if (!isForce) {
    if (reJudgeDotSquare()) {
      return Terms.dotSquare.desc;
    }
    if (reJudgeJumpSquare()) {
      return Terms.jumpSquare.desc;
    }
    if (judgeSmallLedge()) {
      return Terms.smallLedge.desc;
    }
    if (judgeBigLedge()) {
      return Terms.bigLedge.desc;
    }
  } else {
    return forceJudge();
  }

  return finalTerms.desc;
}
